package com.soo.hoo.core.handler;

import cn.hutool.core.collection.CollUtil;
import com.soo.hoo.core.exception.GlobalException;
import com.soo.hoo.core.model.Result;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.HttpStatus;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * <p>
 * 全局异常处理
 * </p>
 *
 * @author 杨燚
 * @since 2021-06-10
 */
@RestController
@ControllerAdvice
@Log4j2
public class GlobalExceptionHandler {

    /**
     * 全局处理服务器内部异常
     *
     * @return 异常信息
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Throwable.class)
    public Result<String> handleThrowable(Throwable e) {
        if (e.getCause() != null) {
            e.getCause().printStackTrace();
        } else {
            e.printStackTrace();
        }
        return Result.failure(e.getMessage());
    }

    /**
     * 全局处理自定义异常
     *
     * @return 异常信息
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(GlobalException.class)
    public Result<String> handleGlobalException(GlobalException e) {
        if (e.getCode() == null) {
            return Result.failure(e.getMessage());
        }
        return Result.failure(e.getCode(), e.getMessage());
    }

    /**
     * 全局处理空指针异常
     *
     * @return 异常信息
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(NullPointerException.class)
    public Result<String> handleNullPointerException(NullPointerException e) {
        e.printStackTrace();
        return Result.failure("空指针异常：" + e.getMessage());
    }

    /**
     * 全局处理参数校验异常
     *
     * @return 异常信息
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
        if (CollUtil.isNotEmpty(allErrors)) {
            String defaultMessage = allErrors.get(0).getDefaultMessage();
            return Result.failure(defaultMessage);
        }
        return Result.failure(e.getMessage());
    }

}
